import React, {forwardRef, JSX, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState} from "react";
import {Button, Form, FormInstance, message, Modal, Pagination, Popconfirm, Space, Table, TableProps} from "antd";
import {SorterResult, TableRowSelection} from "antd/es/table/interface";
import SearchForm from "./SearchForm";
import {
    DeleteOutlined,
    EditOutlined,
    ExclamationCircleFilled,
    ExportOutlined,
    EyeOutlined,
    MenuFoldOutlined,
    MenuUnfoldOutlined,
    PlusCircleOutlined,
    PrinterOutlined,
    RedoOutlined,
    SearchOutlined
} from "@ant-design/icons";
import EditForm, {EditFormProps, EditLayout} from "./EditForm.tsx";
import {useReactToPrint} from "react-to-print";
import DictItems from "./DictItems.tsx";
import {convertObjetToAttrs, getObjectKeyIfHasChildren, removeIf} from "../../libs/utils.ts";
import {Key} from "rc-table/lib/interface";
import {useCheckPermission} from "../../hooks/usePermissions.tsx";
import CustomDeleteIcon from "../CustomIcon/CustomDeleteIcon.tsx";
import {AddButton, CommonButton, DelButton, EditButton, SearchButton} from "../../css/CommonButton.tsx";
import {HeaderCell, HeaderContent, TableContainer} from "../../css/CommonTable.tsx";
import {ColumnConfig} from "./TableHeader.tsx";
import "../../css/table.css";

export type Actions<T> = {
    onFetchList?: (pageNumber?: number, pageSize?: number, searchParams?: any, sortKey?: string, sortType?: "asc" | "desc") => void,
    onFetchDetail?: (row: T) => T,
    onDelete?: (row: T) => void,
    onDeleteBatch?: (rows: T[]) => void,
    onUpdate?: (row: T) => void,
    onCreate?: (row: T) => void,
}

export type ColumnsConfig<RecordType = unknown> = ColumnConfig<RecordType> [];

export type ActionConfig<T> = {
    hidden?: boolean,
    title?: string,
    fixedRight?: boolean,
    width?: number | string,
    detailButtonEnable?: boolean,
    editButtonEnable?: boolean,
    deleteButtonEnable?: boolean,
    customActions?: (data: T) => JSX.Element | null
}

export type AntdCrudProps<T> = {
    columns: ColumnsConfig<T>,
    actions: Actions<T>,
    actionConfig?: ActionConfig<T>,
    formRenderFactory?: (position: "edit" | "search", columnConfig: ColumnConfig, form: FormInstance) => JSX.Element | null
    customButton?: () => React.ReactNode | null,
    dataSource: any,
    pageNumber?: number,
    pageSize?: number,
    paginationHidden?: boolean,
    totalRow?: number,
    loading?: boolean,
    defaultExpandedAllRow?: boolean,
    tableAttrs?: TableProps<any>,
    addButtonEnable?: boolean,
    rowSelectEnable?: boolean,
    intelligentFilling?: EditFormProps<any>['intelligentFilling'],
    initSearchParams?: any,
    onSearchValueInit?: (key: string) => any,
    editLayout?: EditLayout,
    tableAlias?: string,
    needHideSearchForm?: boolean,
    usePermission?: string
}

function download(columns: ColumnsConfig<any>, dataSource: any[]) {
    let cvs = '';
    columns.map((column) => {
        cvs += `${column.title}, `;
    })
    cvs += '\r\n'

    dataSource.map((data) => {
        columns.map((column) => {
            cvs += `${data[column.key as string]}, `;
        })
        cvs += '\r\n'
    });

    const _utf = "\uFEFF";
    const url = 'data:application/csv;charset=utf-8,' + _utf + encodeURIComponent(cvs);
    const link = document.createElement("a");
    link.href = url;
    link.style.cssText = "visibility:hidden";
    link.download = "data.csv";
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
}

const AntdCrud = forwardRef(function AntdCrud<T>({
                                                     columns,
                                                     dataSource,
                                                     actions,
                                                     actionConfig,
                                                     formRenderFactory,
                                                     customButton,
                                                     pageNumber = 1,
                                                     pageSize = 10,
                                                     totalRow = 0,
                                                     loading,
                                                     paginationHidden = false,
                                                     tableAttrs = {},
                                                     defaultExpandedAllRow = true,
                                                     addButtonEnable = true,
                                                     rowSelectEnable = true,
                                                     intelligentFilling,
                                                     initSearchParams,
                                                     onSearchValueInit,
                                                     editLayout,
                                                     tableAlias,
                                                     needHideSearchForm = false,
                                                     usePermission
                                                 }: AntdCrudProps<T>, ref: any) {

    const tableRef = useRef<any>(null);
    const { confirm } = Modal;
    const [form] = Form.useForm();
    const handlePrint = useReactToPrint({
        documentTitle: "表格打印",
        contentRef: tableRef,
        pageStyle: `@page {padding-top:10px;} @media print {body { font-family: "SimSun", "宋体", serif;}}`,
    });

    const [searchKey, setSearchKey] = useState(0);
    const hasQueryPermission = useCheckPermission(`/api/v1/${usePermission ? usePermission : tableAlias}/query`)
    const hasRemovePermission = useCheckPermission(`/api/v1/${usePermission ? usePermission : tableAlias}/remove`)
    const hasSavePermission = useCheckPermission(`/api/v1/${usePermission ? usePermission : tableAlias}/save`)
    const [isPlaying, setIsPlaying] = useState(false);
    dataSource = convertObjetToAttrs(dataSource);

    const [messageApi, contextHolder] = message.useMessage();
    const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
    const [selectedRows, setSelectedRows] = useState<T[]>([]);
    const [selectCount, setSelectCount] = useState(0);
    const [modalTitle, setModalTitle] = useState("");
    const [isModalOpen, setIsModalOpen] = useState(false);
    const [modalRow, setModalRow] = useState<T | null>(null);
    const [confirmLoading, setConfirmLoading] = useState(false);
    const [tableSize] = useState<"small" | "middle" | "large">("large");
    const [formItemDisabled, setFormItemDisabled] = useState<boolean>(false);
    const [defaultExpandedRowKeys, setDefaultExpandedRowKeys] = useState<Key[]>([]);

    const [localPageNumber, setLocalPageNumber] = useState(pageNumber)
    const [localPageSize, setLocalPageSize] = useState(pageSize)

    const [searchParams, setSearchParams] = useState(initSearchParams)
    const [sortKey, setSortKey] = useState<string | undefined>()
    const [sortType, setSortType] = useState<"asc" | "desc" | undefined>()

    const [isHiddenSearch, setIsHiddenSearch] = useState(true)

    actionConfig = {
        title: '操作',
        fixedRight: true,
        width: 210,
        detailButtonEnable: false,
        editButtonEnable: true,
        deleteButtonEnable: true,
        ...actionConfig
    } as ActionConfig<T>

    const selectNone = () => {
        setSelectedRowKeys([]);
        setSelectedRows([]);
        setSelectCount(0);
    };

    useEffect(() => {
        if (defaultExpandedAllRow) {
            const keys = getObjectKeyIfHasChildren(dataSource);
            setDefaultExpandedRowKeys(keys)
        }
    }, [dataSource, defaultExpandedAllRow])

    const tableColumns = actionConfig.hidden ? columns : [...columns, {
        title: actionConfig.title,
        key: 'action',
        fixed: actionConfig.fixedRight ? 'right' : undefined,
        width: '60px',
        render: (_: any, row: React.SetStateAction<T | null>) => (
            <Space size="middle">
                {(actionConfig?.detailButtonEnable && hasQueryPermission) && <a onClick={() => {
                    setModalRow(row)
                    setModalTitle("查看")
                    setIsModalOpen(true)
                    setFormItemDisabled(true)
                }}> <EyeOutlined/> 查看 </a>}

                {(actionConfig?.editButtonEnable && hasSavePermission) && <a onClick={() => {
                    setModalRow(row)
                    setModalTitle("编辑")
                    setIsModalOpen(true)
                }}> <EditOutlined/> 编辑 </a>}

                {(actionConfig?.deleteButtonEnable && hasRemovePermission) && <Popconfirm
                    title="确定删除？"
                    description="您确定要删除这条数据吗？"
                    okButtonProps={{loading: confirmLoading}}
                    onConfirm={() => {
                        setConfirmLoading(true)
                        actions.onDelete && actions.onDelete(row as T)
                        setConfirmLoading(false)
                        doRefresh()
                    }}
                    okText="确定"
                    cancelText="取消"
                >
                    <a style={{color: "red"}}> <CustomDeleteIcon/> 删除 </a>
                </Popconfirm>}
            </Space>
        ),
    } as any];

    tableColumns.forEach((columnConfig) => {
        if (columnConfig.dict && !columnConfig["render"]) {
            columnConfig["render"] = (_text: any, data: any) => {
                return (
                    <DictItems columnConfig={columnConfig} columnData={data}/>
                )
            }
        }
    });

    useEffect(() => {
        actions.onFetchList?.(localPageNumber, localPageSize, searchParams, sortKey, sortType);
    }, [localPageNumber, localPageSize, searchParams, sortKey, sortType, searchKey])

    const doRefresh = useCallback(() => {
        setTimeout(() => {
            actions.onFetchList?.(localPageNumber, localPageSize, searchParams, sortKey, sortType);
        }, 200)
    }, []);

    useImperativeHandle(ref, () => ({
        openAddModal: () => {
            setModalRow(null);
            setModalTitle("新增");
            setIsModalOpen(true);
        },
        onSearch: (params: any) => {
            setLocalPageNumber(1)
            setSearchParams(params)
        },
    }));

    const centeredColumns = useMemo(() => {
        return tableColumns.map(column => {
            const newColumn = {...column};
            if (!newColumn.render) {
                newColumn.render = (text: any) => (
                    <HeaderContent>
                        <HeaderCell>{text}</HeaderCell>
                    </HeaderContent>
                );
            } else {
                const originalRender = newColumn.render;
                newColumn.render = (text: any, record: any, index: number) => (
                    <HeaderContent>
                        <HeaderCell> {originalRender(text, record, index)}</HeaderCell>
                    </HeaderContent>
                );
            }
            return newColumn;
        });
    }, [tableColumns]);

    const finalColumns = [...centeredColumns];

    const showConfirm = () => {
        confirm({
            title: "您确定要删除所选的数据吗？",
            icon: <ExclamationCircleFilled />,
            onOk() {
                setConfirmLoading(true)
                actions.onDeleteBatch && actions.onDeleteBatch(selectedRows);
                setConfirmLoading(false)
                doRefresh();
            },
            onCancel() {
                console.log('Cancel');
            },
        });
    };

    return (
        <div style={{
            borderTop: "1px solid #1890ff",
            display: 'flex',
            flexDirection: 'column',
            height: 'calc(100vh - 100px)',
            overflow: 'hidden'
        }}>
            <Space style={{display: "flex", justifyContent: "space-between",height: '50px', padding: "5px 20px 5px 20px"}}>
                <Space align={"center"}>
                    {customButton?.()}
                    {needHideSearchForm && <Button onClick={() => {
                    }}><a target="_blank" href="https://aiflowy.tech/zh/product/llm/addLlm.html"
                          style={{fontSize: 12}}>大模型配置参考地址</a></Button>}
                    {!needHideSearchForm && (addButtonEnable && hasSavePermission) && <AddButton onClick={() => {
                        setModalRow(null);
                        setModalTitle("新增")
                        setIsModalOpen(!isModalOpen)
                    }}><PlusCircleOutlined/>新增</AddButton>}

                    {addButtonEnable && hasSavePermission && <EditButton onClick={() => {
                        setModalRow(selectedRows[0])
                        setModalTitle("修改")
                        setIsModalOpen(true)
                    }}><EditOutlined style={{fontSize: '18px', padding: "0px 2px 2px 2px"}}/>修改</EditButton>}

                    {(actionConfig?.deleteButtonEnable && hasRemovePermission) && <DelButton onClick={showConfirm}>
                        <DeleteOutlined
                            style={{fontSize: '18px', padding: "0px 2px 2px 2px"}}/>删除</DelButton>}

                    <CommonButton onClick={() => {
                        download(columns, dataSource);
                    }}><ExportOutlined/>导出</CommonButton>

                    <CommonButton onClick={() => {
                        messageApi.success("打印数据准备中...");
                        handlePrint()
                    }}><PrinterOutlined/>打印</CommonButton>

                </Space>
                <Space align={"center"} size={"middle"}>

                    <Button
                        title="隐藏查询条件"
                        type="text"
                        icon={isPlaying ? <MenuFoldOutlined/> : <MenuUnfoldOutlined/>}
                        onClick={() => {
                            setIsHiddenSearch(!isHiddenSearch)
                        }
                        }
                        style={{
                            width: '40px',
                            height: '40px',
                            padding: '4px 0',
                            display: 'flex',
                            alignItems: 'center',
                            justifyContent: 'center',
                            border: 'none',
                            background: 'none'
                        }}
                    />

                    <Button
                        type="text"
                        title="重置"
                        icon={<RedoOutlined/>}
                        onClick={() => {
                            setIsPlaying(!isPlaying);
                            form.resetFields();
                        }
                        }
                        style={{
                            width: '40px',
                            height: '40px',
                            padding: '4px 0',
                            display: 'flex',
                            alignItems: 'center',
                            justifyContent: 'center',
                            border: 'none',
                            background: 'none'
                        }}
                    />

                    <SearchButton onClick={() => {
                        const values = form.getFieldsValue();
                        setSearchParams(values);
                        setSearchKey(prev => prev + 1);
                    }}><SearchOutlined/>查询</SearchButton>

                </Space>
            </Space>
            {contextHolder}
            {
                !needHideSearchForm && isHiddenSearch && <SearchForm columns={columns} colSpan={6}
                                                                     onSearchValueInit={onSearchValueInit}
                                                                     formRenderFactory={formRenderFactory}
                                                                     form={form}
                />
            }
            <EditForm title={modalTitle}
                      intelligentFilling={intelligentFilling}
                      columns={columns}
                      open={isModalOpen}
                      onSubmit={() => {
                          setIsModalOpen(false)
                          setLocalPageNumber(1)
                          doRefresh()
                      }}
                      onCancel={() => {
                          setIsModalOpen(false)
                          setFormItemDisabled(false)
                          setModalRow(null)
                      }}
                      actions={actions}
                      onActionsInvokeAfter={doRefresh}
                      formRenderFactory={formRenderFactory}
                      row={modalRow as T}
                      formReadOnly={formItemDisabled}
                      layout={editLayout}
            />

            <TableContainer ref={tableRef} style={{
                borderTop: '1px solid #bfbfbf',
                borderLeft: '1px solid #f0f0f0',
                borderRight: '1px solid #f0f0f0',
                flex: 1,
                background: 'white',
                display: 'flex',
                flexDirection: 'column',
                overflow: 'hidden',
                minHeight: 0,
                position: 'relative'
            }}>
                {/* 表格区域 - 占据主要空间 */}
                <div style={{
                    flex: 1,
                    overflow: 'auto',
                    display: 'flex',
                    flexDirection: 'column'
                }}>
                    <Table
                        columns={finalColumns}
                        dataSource={dataSource}
                        rowKey="id"
                        bordered
                        expandable={{
                            expandedRowKeys: defaultExpandedRowKeys,
                            onExpand: (expanded, record) => {
                                if (expanded) {
                                    setDefaultExpandedRowKeys(defaultExpandedRowKeys.concat(record["id"]))
                                } else {
                                    setDefaultExpandedRowKeys(removeIf(defaultExpandedRowKeys, (key) => {
                                        return key == record["id"];
                                    }))
                                }
                            }
                        }}
                        size={tableSize}
                        loading={loading}
                        onChange={(pagination, _, sorter) => {
                            setLocalPageNumber(pagination.current || 1);
                            setLocalPageSize(pagination.pageSize || pageSize)
                            if (sorter) {
                                const result = sorter as SorterResult<any>;
                                setSortKey(result.field as string);
                                if (result.order) {
                                    setSortType(result.order === "ascend" ? "asc" : "desc")
                                } else {
                                    setSortKey(undefined)
                                    setSortType(undefined)
                                }
                            }
                        }}
                        rowSelection={rowSelectEnable ? {
                            type: 'checkbox',
                            selectedRowKeys,
                            onChange: (selectedRowKeys: React.Key[], selectedRows: T[]) => {
                                setSelectedRows(selectedRows);
                                setSelectedRowKeys([...selectedRowKeys]);
                                setSelectCount(selectedRows.length);
                            }
                        } as TableRowSelection<any> : undefined}
                        style={{
                            flex: 1,
                            display: 'flex',
                            flexDirection: 'column',
                            width: '100%',
                            height: 'auto',
                            fontSize:'16px'
                        }}
                        scroll={{
                            x: 'max-content',
                            y: '100vh' // 动态计算高度，预留分页区域空间
                        }}
                        pagination={false}
                        components={{
                            header: {
                                cell: (props: any) => (
                                    <th {...props} style={{
                                        ...props.style,
                                        textAlign: 'center',
                                        backgroundColor: '#f0f5ff',
                                        whiteSpace: 'nowrap',
                                        overflow: 'hidden',
                                        textOverflow: 'ellipsis'
                                    }}/>
                                )
                            }
                        }}
                        {...tableAttrs}
                    />
                </div>
                {{paginationHidden} &&
                    <div style={{
                        position: 'sticky',
                        bottom: 0,
                        left: 0,
                        right: 0,
                        background: 'white',
                        padding: '16px 24px',
                        borderTop: '1px solid #f0f0f0',
                        zIndex: 1000,
                        display: 'flex',
                        justifyContent: 'space-between',
                        alignItems: 'center',
                        flexShrink: 0,
                        height: '48px',
                        marginTop: 'auto'
                    }}>
                        {/* 左侧：选中统计信息和操作按钮 */}
                        <div style={{
                            overflow: 'visible ',
                            display: 'flex',
                            alignItems: 'center',
                            gap: '16px',
                            flex: 1
                        }}>
                            {selectCount > 0 ? (
                                <>
                                    <span style={{
                                        fontSize: '14px',
                                        color: '#1890ff',
                                        fontWeight: 500
                                    }}>
                                        已选择 <span style={{fontWeight: 'bold'}}>{selectCount}</span> 项
                                    </span>

                                    <Popconfirm
                                        title="确定删除所选数据？"
                                        description="删除后数据将无法恢复，请谨慎操作！"
                                        okButtonProps={{loading: confirmLoading}}
                                        onConfirm={() => {
                                            setConfirmLoading(true);
                                            actions.onDeleteBatch && actions.onDeleteBatch(selectedRows);
                                            setConfirmLoading(false);
                                            doRefresh();
                                        }}
                                        okText="确定删除"
                                        cancelText="取消"
                                    >
                                        <Button
                                            type="link"
                                            danger
                                            size="small"
                                            icon={<DeleteOutlined />}
                                            style={{padding: '0 8px', height: '24px'}}
                                        >
                                            全部删除
                                        </Button>
                                    </Popconfirm>

                                    <Button
                                        type="link"
                                        size="small"
                                        onClick={selectNone}
                                        style={{padding: '0 8px', height: '24px', color: '#999'}}
                                    >
                                        取消选择
                                    </Button>
                                </>
                            ) : (
                                <span style={{
                                    fontSize: '14px',
                                    color: '#999'
                                }}>
                            未选择任何项目
                        </span>
                            )}
                        </div>

                        {/* 右侧：分页控件 */}
                        <div style={{
                            display: 'flex',
                            alignItems: 'center',
                            gap: '8px',
                            position: 'relative',
                            zIndex: 1001
                        }}>
                            <Pagination
                                current={localPageNumber}
                                pageSize={localPageSize}
                                total={totalRow || 0}
                                showSizeChanger
                                showQuickJumper
                                showTotal={(total, range) => {
                                    const totalPages = Math.ceil(total / localPageSize);
                                    return `第 ${range[0]}-${range[1]} 条 / 共 ${total} 条 / ${totalPages} 页`;
                                }}
                                onChange={(page, pageSize) => {
                                    setLocalPageNumber(page);
                                    setLocalPageSize(pageSize || 10);
                                }}
                                onShowSizeChange={(_current, size) => {
                                    setLocalPageSize(size);
                                    setLocalPageNumber(1);
                                }}
                                pageSizeOptions={['10','20','50','100']}
                                style={{margin: 0}}
                            />
                        </div>
                    </div>}
            </TableContainer>

        </div>
    )
})

export default AntdCrud